package customer

import (
	"context"
	stdErrors "errors"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	"github.com/google/wire"
	"reflect"
	"sieve_admin_server_userpass/app/dao/business_type"
	"sieve_admin_server_userpass/app/dao/sieve_config"
	"sieve_admin_server_userpass/app/dao/user"
	"sieve_admin_server_userpass/app/schema"
	serviceSys "sieve_admin_server_userpass/app/service/sys"
	serviceUtil "sieve_admin_server_userpass/app/service/util"
	"sieve_admin_server_userpass/lib/util/convert"
	"sieve_admin_server_userpass/lib/util/errors"
	pkgTime "sieve_admin_server_userpass/pkg/time"
	"sieve_admin_server_userpass/pkg/util"
	pkgUtil "sieve_admin_server_userpass/pkg/util"
	"strconv"
	"strings"
	"time"
)

var (
	BusinessTypeSet = wire.NewSet(wire.Struct(new(BusinessTypeSrv), "*"))
)

type BusinessTypeSrv struct {
	UserSrv          *UserSrv
	RoleSrv          *serviceSys.RoleSrv
	UserAuthSrv      *UserAuthSrv
	BusinessPriceSrv *BusinessPriceSrv
	SieveConfigSrv   *SieveConfigSrv
	BusinessTypeRepo *business_type.BusinessTypeRepo
}

var (
	bizConfig = []*business_type.BusinessTypeConfiguration{
		{
			Name:      "filter",
			Desc:      "ws筛有效",
			UnitPrice: 2, // 积分和人命币的换算比例：1积分=1/10000 元 这里的单位是积分
		},
		{
			Name:      "live",
			Desc:      "ws筛活跃",
			UnitPrice: 20,
		},
		{
			Name:      "gender",
			Desc:      "ws筛性别",
			UnitPrice: 50,
		},
		{
			Name:      "fb",
			Desc:      "FB筛有效",
			UnitPrice: 5,
		},
		{
			Name:      "ins",
			Desc:      "INS筛有效",
			UnitPrice: 5,
		},
		{
			Name:      "linkedin",
			Desc:      "领英筛有效",
			UnitPrice: 50,
		},
		{
			Name:      "linkedinSenior",
			Desc:      "领英高级筛",
			UnitPrice: 50,
		},
		{
			Name:      "linkedinStandard",
			Desc:      "领英标准筛",
			UnitPrice: 10,
		},
		{
			Name:      "amazon",
			Desc:      "amazon筛有效",
			UnitPrice: 30,
		},
		{
			Name:      "Viber",
			Desc:      "Viber筛有效",
			UnitPrice: 10,
		},
		{
			Name:      "ViberActive",
			Desc:      "Viber筛活跃",
			UnitPrice: 50,
		},

		{
			Name:      "line",
			Desc:      "line筛有效",
			UnitPrice: 50,
		},
		{
			Name:      "lineGender",
			Desc:      "line筛性别",
			UnitPrice: 100,
		},

		{
			Name:      "zalo",
			Desc:      "zalo筛有效",
			UnitPrice: 15,
		},

		{
			Name:      "zaloGender",
			Desc:      "zalo筛性别",
			UnitPrice: 50,
		},

		{
			Name:      "twitter",
			Desc:      "twitter筛有效",
			UnitPrice: 10,
		},

		{
			Name:      "skype",
			Desc:      "skype筛有效",
			UnitPrice: 50,
		},

		{
			Name:      "tg",
			Desc:      "tg筛有效",
			UnitPrice: 100,
		},

		{
			Name:      "tgActive",
			Desc:      "tg筛活跃",
			UnitPrice: 120,
		},

		{
			Name:      "momo",
			Desc:      "momo筛有效",
			UnitPrice: 50,
		},

		{
			Name:      "mtnMomo",
			Desc:      "mtnMomo筛有效",
			UnitPrice: 50,
		},

		{
			Name:      "mtnMomo",
			Desc:      "mtnMomo筛有效",
			UnitPrice: 50,
		},

		{
			Name:      "microsoft",
			Desc:      "microsoft筛有效",
			UnitPrice: 30,
		},

		{
			Name:      "trueMoney",
			Desc:      "trueMoney筛有效",
			UnitPrice: 100,
		},

		{
			Name:      "botim",
			Desc:      "botim筛有效",
			UnitPrice: 50,
		},

		{
			Name:      "operatorStandard",
			Desc:      "运营商标准筛",
			UnitPrice: 500,
		},
		{
			Name:      "operatorPremium",
			Desc:      "运营商高级筛",
			UnitPrice: 600,
		},
		{
			Name:      "phoneCheck",
			Desc:      "空号检测",
			UnitPrice: 50,
		},
		{
			Name:      "tk",
			Desc:      "TK筛有效",
			UnitPrice: 50,
		},
		{
			Name:      "tkStandard",
			Desc:      "TK格式筛",
			UnitPrice: 150,
		},
	}
)

func (a *BusinessTypeSrv) GetBusinessTypes(ctx context.Context) interface{} {

	respGetAll, err := a.GetAll(ctx)
	if err != nil {
		return err
	}
	return respGetAll
	// return bizConfig
}

func (a *BusinessTypeSrv) GetAll(ctx context.Context) ([]interface{}, error) {

	a.WaitFinished()
	var (
		querySQL = fmt.Sprintf(`
				SELECT
					*
				FROM
					business_type_configuration
				WHERE role_id = '%v' AND business_type_configuration.deleted = 0
`, adminAccount.RoleId)
	)

	return a.BusinessTypeRepo.QueryRaw(ctx, querySQL, business_type.BusinessTypeConfiguration{})
}

// 查询 uid 对应的角色是否有配置过业务类型
func (a *BusinessTypeSrv) getByUid(ctx context.Context, uid int, name string) ([]interface{}, error) {

	var (
		querySQL = fmt.Sprintf(`
				SELECT
					business_type_configuration.*
				FROM
					business_type_configuration
				INNER JOIN (
					SELECT 
						user.role_id as role_id,
						user.id as uid
					FROM
						user
					WHERE user.id = %v AND user.deleted = 0
				) user_role ON user_role.role_id = business_type_configuration.role_id
				WHERE name = '%v' AND business_type_configuration.deleted = 0
`, uid, name)
	)

	return a.BusinessTypeRepo.QueryRaw(ctx, querySQL, business_type.BusinessTypeConfiguration{})
}

func (a *BusinessTypeSrv) Create(ctx context.Context, uid int, item map[string]interface{}) interface{} {

	if v, ok := item["sieve_source_config_id"]; !ok {
		return stdErrors.New(fmt.Sprintf("'筛源'不可缺失"))
	} else {
		// 检测这个筛源，已经有了相同的业务类型
		if err := a.checkDup(ctx, item["name"].(string), 0, v.(uint64)); err != nil {
			return err
		}
	}

	respUser, err := a.UserSrv.GetByUID(ctx, uint64(uid))
	if err != nil {
		return stdErrors.New(fmt.Sprintf("服务器错误"))
	}

	// 代理商没有 冻结/解冻权限
	if !a.RoleSrv.IsAdminRoleId(respUser.RoleId) {
		return stdErrors.New(fmt.Sprintf("只有管理角色才可以创建类型配置"))
	}

	var roleID uint64
	if v, ok := item["role_id"]; ok {
		roleID = v.(uint64)
	} else {
		if resp, err := a.UserSrv.GetRoleID(ctx, uint64(uid)); err != nil {
			return err
		} else {
			roleID = resp
		}
	}

	var (
		now = time.Now().Unix()
		def = map[string]interface{}{
			"create_at":  now,
			"updated_at": now,
			"role_id":    roleID,
			"creator":    uid,
		}
	)

	for k, v := range def {
		item[k] = v
	}

	return a.BusinessTypeRepo.Create(ctx, item)
}

func (a *BusinessTypeSrv) GetByName(ctx context.Context, name string) (*business_type.BusinessTypeConfiguration, error) {

	var (
		tableName = business_type.BusinessTypeConfiguration{}
		querySQL  = fmt.Sprintf(`
	SELECT * FROM %v 
	WHERE name = '%v'
	AND creator = %v
	AND deleted = 0
`, tableName.TableName(), name, adminAccount.ID)
	)

	req, err := a.BusinessTypeRepo.QueryRaw(ctx, querySQL, business_type.BusinessTypeConfiguration{})
	if err != nil {
		return nil, err
	}

	if req == nil {
		return nil, errors.New(fmt.Sprintf("record not  found"))
	}
	return req[0].(*business_type.BusinessTypeConfiguration), nil
}

func (a *BusinessTypeSrv) Query(ctx context.Context, uid int, reqArgs map[string]interface{}, p schema.PaginationParam) interface{} {

	uid = int(adminAccount.ID)
	if resp, err := a.UserSrv.GetRoleID(ctx, uint64(uid)); err != nil {
		return err
	} else {
		reqArgs["role_id"] = resp
	}

	type columnType struct {
		ID               uint64  `json:"id"`                 //  自增id
		Name             string  `json:"name"`               //  业务类型
		Desc             string  `json:"desc"`               //  业务类型描述
		SieveSourceLabel *string `json:"sieve_source_label"` //  筛源标签
		SieveSourceName  *string `json:"sieve_source_name"`  //  筛源名称
		SieveSourceAlias *string `json:"sieve_source_alias"` //  筛源别名
		UnitPrice        uint64  `json:"unit_price"`         //  单价（指的是筛选1个号码的价格）
		Status           int64   `json:"status"`             //  1:启用,2:禁用
		RoleId           uint64  `json:"role_id"`            //  创建人所属角色
		Creator          int64   `json:"creator"`            //  创建人（修改人）
		CreatorName      *string `json:"creator_name"`
		CreateAt         int64   `json:"create_at"`
		UpdatedAt        int64   `json:"updated_at"`
	}

	var (
		btcTableName               = business_type.BusinessTypeConfiguration{}.TableName()
		userTableName              = user.User{}.TableName()
		sieveSourceConfigTableName = sieve_config.SieveSourceConfig{}.TableName()
		joinString                 = []string{fmt.Sprintf(
			`
			LEFT JOIN %v ON %v.id = %v.creator and %v.deleted = 0`,
			userTableName,
			userTableName,
			btcTableName,
			userTableName,
		), fmt.Sprintf(
			`
			LEFT JOIN %v ON %v.id = %v.sieve_source_config_id and %v.deleted = 0`,
			sieveSourceConfigTableName,
			sieveSourceConfigTableName,
			btcTableName,
			sieveSourceConfigTableName,
		)}
		repKeys = []string{
			fmt.Sprintf("%v.id as id", btcTableName),
			fmt.Sprintf("%v.name as name", btcTableName),
			fmt.Sprintf("%v.desc as `desc`", btcTableName),
			fmt.Sprintf("%v.label as sieve_source_label", sieveSourceConfigTableName),
			fmt.Sprintf("%v.name as sieve_source_name", sieveSourceConfigTableName),
			fmt.Sprintf("%v.alias as sieve_source_alias", sieveSourceConfigTableName),
			fmt.Sprintf("%v.unit_price as unit_price", btcTableName),
			fmt.Sprintf("%v.status as status", btcTableName),
			fmt.Sprintf("%v.role_id as role_id", btcTableName),
			fmt.Sprintf("%v.creator as creator", btcTableName),
			fmt.Sprintf("%v.account as creator_name", userTableName),
			fmt.Sprintf("%v.create_at as create_at", btcTableName),
			fmt.Sprintf("%v.updated_at as updated_at", btcTableName),
		}
	)

	ctx = context.WithValue(
		context.WithValue(ctx, "join", strings.Join(joinString, " ")),
		"column_types", columnType{},
	)

	req, err := a.BusinessTypeRepo.Query(ctx, reqArgs, p, repKeys)
	if err != nil {
		return err
	}
	return req
}

func (a *BusinessTypeSrv) QueryTypes(ctx context.Context, reqArgs map[string]interface{}, p schema.PaginationParam, repKeys []string) interface{} {

	req, err := a.BusinessTypeRepo.Query(ctx, reqArgs, p, repKeys)
	if err != nil {
		return err
	}
	return req
}

func (a *BusinessTypeSrv) Enable(ctx context.Context, uid int, reqArgs map[string]interface{}) error {

	respUser, err := a.UserSrv.GetByUID(ctx, uint64(uid))
	if err != nil {
		return stdErrors.New(fmt.Sprintf("服务器错误"))
	}

	if !a.RoleSrv.IsAdminRoleId(respUser.RoleId) {
		return errors.New(fmt.Sprintf("只有管理员角色才可以修改"))
	}

	var (
		now        = time.Now().Unix()
		updateKeys = map[string]interface{}{
			"updated_at": now,
			"status":     1,
		}
		queryKeys = map[string]interface{}{
			"id": reqArgs["id"],
		}
	)

	if resp, err := a.UserSrv.GetRoleID(ctx, uint64(uid)); err != nil {
		return err
	} else {
		queryKeys["role_id"] = resp
	}

	return a.BusinessTypeRepo.Update(ctx, updateKeys, queryKeys)
}

func (a *BusinessTypeSrv) Disable(ctx context.Context, uid int, reqArgs map[string]interface{}) error {

	respUser, err := a.UserSrv.GetByUID(ctx, uint64(uid))
	if err != nil {
		return stdErrors.New(fmt.Sprintf("服务器错误"))
	}

	if !a.RoleSrv.IsAdminRoleId(respUser.RoleId) {
		return errors.New(fmt.Sprintf("只有管理员角色才可以修改"))
	}
	var (
		now        = time.Now().Unix()
		updateKeys = map[string]interface{}{
			"updated_at": now,
			"status":     2,
		}
		queryKeys = map[string]interface{}{
			"id": reqArgs["id"],
		}
	)
	if resp, err := a.UserSrv.GetRoleID(ctx, uint64(uid)); err != nil {
		return err
	} else {
		queryKeys["role_id"] = resp
	}

	return a.BusinessTypeRepo.Update(ctx, updateKeys, queryKeys)
}

func (a *BusinessTypeSrv) CreateOrUpdate(ctx context.Context, uid int, name string, reqArgs map[string]interface{}, args ...interface{}) error {

	var (
		tableName = business_type.BusinessTypeConfiguration{}
		querySQL  = fmt.Sprintf(`
	SELECT * FROM %v 
	WHERE name = '%v'
	AND creator = %v
	AND deleted = 0
`, tableName.TableName(), name, uid)
	)

	req, err := a.BusinessTypeRepo.QueryRaw(ctx, querySQL, business_type.BusinessTypeConfiguration{})
	if err != nil {
		return err
	}

	if req == nil {
		resp := a.Create(ctx, uid, reqArgs)
		if v, ok := resp.(error); ok {
			return v
		}
		return nil
	}

	for _, v := range req {

		respBiz := v.(*business_type.BusinessTypeConfiguration)
		if respBiz.Desc == reqArgs["desc"] && respBiz.UnitPrice == reqArgs["unit_price"] {
			return nil
		}
	}

	return a.Update(ctx, uid, reqArgs)
}

func (a *BusinessTypeSrv) UpdateBatch(ctx context.Context, uid int, reqArgs map[string]interface{}) error {

	if _, ok := reqArgs["ids"]; !ok {
		return errors.New("请求参数错误")
	}
	if _, ok := reqArgs["sieve_source_config_id"]; !ok {
		return errors.New("请求参数错误")
	}
	var (
		updateSQL = fmt.Sprintf(`
		UPDATE 
			business_type_configuration
		SET sieve_source_config_id = %v
		WHERE id IN (%v)
`, reqArgs["sieve_source_config_id"], strings.Join(strings.Split(reqArgs["ids"].(string), "|"), ","))
	)

	_, err := a.BusinessTypeRepo.ExecRaw(ctx, updateSQL)
	return err
}

func (a *BusinessTypeSrv) dealPriceUpdate(ctx context.Context, id uint64, unitPrice uint64) (bool, error) {

	var (
		reqArgs = map[string]interface{}{
			"id": id,
		}
		p = schema.PaginationParam{
			OnlyData: true,
		}
		repKeys      = []string{"*"}
		dealBizPrice bool
	)
	resp, err := a.BusinessTypeRepo.Query(ctx, reqArgs, p, repKeys)
	if err != nil {
		return false, err
	}

	for _, v := range resp.(map[string]interface{})["list"].([]interface{}) {
		item := v.(*business_type.BusinessTypeConfiguration)
		if item.UnitPrice != unitPrice {
			dealBizPrice = true
		}
	}

	// 当系统默认价格发生修改时，渠道主的业务方案自动切换至“系统默认”
	if dealBizPrice {
		var (
			updateSQL = fmt.Sprintf(`
UPDATE user,business_price_scheme
SET user.business_price_id = business_price_scheme.id 
WHERE business_price_scheme.def = 1 AND business_price_scheme.deleted = 0 AND user.business_price_id > 0 AND user.deleted = 0
`)
		)

		if _, err = a.BusinessTypeRepo.ExecRaw(ctx, updateSQL); err != nil {
			return false, err
		}

		if err = a.BusinessPriceSrv.SyncBusinessPriceUserCount(); err != nil {
			return false, err
		}
	}

	return dealBizPrice, nil
}

func (a *BusinessTypeSrv) checkDup(ctx context.Context, name string, id, sieveConfigId uint64) error {

	var oldSieveConfigId uint64
	isUpdate := id != 0
	if isUpdate {
		var (
			querySQL = fmt.Sprintf(`
		SELECT
			*
		FROM
			business_type_configuration
		WHERE id = %v
`, id)
		)
		resp, err := a.BusinessTypeRepo.QueryRaw(ctx, querySQL, business_type.BusinessTypeConfiguration{})
		if err != nil {
			return err
		}

		if len(resp) > 0 {
			oldSieveConfigId = resp[0].(*business_type.BusinessTypeConfiguration).SieveSourceConfigId
		}
		if oldSieveConfigId == sieveConfigId {
			return nil
		}
	}
	var (
		querySQL = fmt.Sprintf(`
		SELECT
			*
		FROM
			business_type_configuration
		WHERE name = '%v' AND sieve_source_config_id = %v AND deleted = 0
`, name, sieveConfigId)
	)
	resp, err := a.BusinessTypeRepo.QueryRaw(ctx, querySQL, business_type.BusinessTypeConfiguration{})
	if err != nil {
		return err
	}

	for _, v := range resp {
		itemData := v.(*business_type.BusinessTypeConfiguration)
		if itemData.Name == name && oldSieveConfigId != sieveConfigId {
			var (
				querySourceSQL = fmt.Sprintf(`
		SELECT
			*
		FROM
			sieve_source_config
		WHERE id = %v AND deleted = 0
`, sieveConfigId)
			)

			var sourceName string
			if resp, err := a.BusinessTypeRepo.QueryRaw(ctx, querySourceSQL, sieve_config.SieveSourceConfig{}); err != nil {

			} else {
				if len(resp) > 0 {
					sourceName = fmt.Sprintf("%v(%v)", resp[0].(*sieve_config.SieveSourceConfig).Label, resp[0].(*sieve_config.SieveSourceConfig).Alias)
				}
			}

			return stdErrors.New(fmt.Sprintf("筛源'%v'已经配置其他业务类型'%v(%v)'", sourceName, itemData.Name, itemData.Desc))
		}
	}
	return nil
}

func (a *BusinessTypeSrv) Update(ctx context.Context, uid int, reqArgs map[string]interface{}) error {

	if _, ok := reqArgs["name"]; !ok {
		return stdErrors.New("参数缺失")
	}

	if _, ok := reqArgs["id"]; !ok {
		return stdErrors.New("参数缺失")
	}

	respUser, err := a.UserSrv.GetByUID(ctx, uint64(uid))
	if err != nil {
		return stdErrors.New(fmt.Sprintf("服务器错误"))
	}

	// 代理商没有 冻结/解冻权限
	if !a.RoleSrv.IsAdminRoleId(respUser.RoleId) {
		return errors.New(fmt.Sprintf("只有管理员角色才可以修改"))
	}

	if v, ok := reqArgs["sieve_source_config_id"]; ok {
		// 检测这个筛源，已经有了相同的业务类型
		if err := a.checkDup(ctx, reqArgs["name"].(string), reqArgs["id"].(uint64), v.(uint64)); err != nil {
			return err
		}
	}

	if _, ok := reqArgs["unit_price"]; ok {
		// 比较价格是否有修改
		if b, err := a.dealPriceUpdate(ctx, reqArgs["id"].(uint64), reqArgs["unit_price"].(uint64)); err != nil {
			return err
		} else {
			defer func() {
				if b {
					_ = a.initSysBusinessPrices()
				}
			}()
		}
	}

	var (
		now        = time.Now().Unix()
		updateKeys = map[string]interface{}{
			"updated_at":             now,
			"desc":                   reqArgs["desc"],
			"unit_price":             reqArgs["unit_price"],
			"sieve_source_config_id": reqArgs["sieve_source_config_id"],
			"creator":                uint64(uid),
		}
		queryKeys = map[string]interface{}{
			"id": reqArgs["id"],
		}
	)

	if v, ok := reqArgs["role_id"]; ok {
		updateKeys["role_id"] = v
	} else {
		if resp, err := a.UserSrv.GetRoleID(ctx, uint64(uid)); err != nil {
			return err
		} else {
			queryKeys["role_id"] = resp
		}
	}

	return a.BusinessTypeRepo.Update(ctx, updateKeys, queryKeys)
}

func (a *BusinessTypeSrv) Delete(ctx context.Context, uid uint64, reqArgs map[string]interface{}) interface{} {

	var (
		id, _ = strconv.ParseUint(fmt.Sprintf("%v", reqArgs["id"]), 10, 64)
	)

	respUser, err := a.UserSrv.GetByUID(ctx, uid)
	if err != nil {
		return err
	}
	if !a.RoleSrv.IsAdminRoleId(respUser.RoleId) {
		return stdErrors.New(fmt.Sprintf("只有管理员角色才可以删除"))
	}

	return a.BusinessTypeRepo.SoftDelete(ctx, id)
}

func (a *BusinessTypeSrv) Export(ctx context.Context, uid int, reqArgs map[string]interface{}) interface{} {

	var (
		p = schema.PaginationParam{
			OnlyData: true,
		}
		queryArgs = map[string]interface{}{
			"id": func() string {
				ids := reqArgs["ids"].(string)
				return fmt.Sprintf("(%v)", strings.Join(strings.Split(ids, "|"), ","))
			}(),
		}
	)

	ctx = context.WithValue(ctx,
		"condition", map[string]string{"id": "IN"},
	)

	respQuery := a.Query(ctx, uid, queryArgs, p)
	if respQuery != nil {
		if _, ok := respQuery.(error); ok && respQuery != nil {
			return respQuery
		}
	}

	selectedItems := []string{
		"id",
		"name",
		"desc",
		"unit_price",
		"status",
		"updated_at",
		"creator_name",
	}
	respQuery = a.export(ctx, respQuery, strings.Join(selectedItems, "|"))
	if respQuery != nil {
		if _, ok := respQuery.(error); ok {
			return respQuery
		}
	}

	return respQuery
}

func (a *BusinessTypeSrv) export(ctx context.Context, req interface{}, selectedItems string) interface{} {

	var (
		statusMap = map[int]string{
			1: "启用",
			2: "禁用",
		}
		selectedItemMap = make(map[string]int)
		xlsx            = excelize.NewFile()
		categories      = map[string]string{"A1": "序号", "B1": "业务类型", "C1": "业务类型名称", "D1": "单价", "E1": "状态", "F1": "最后修改时间", "G1": "修改人"}
		colWidths       = map[string]float64{"A": 5, "B": 10, "C": 15, "D": 10, "E": 8, "F": 20, "G": 12}
	)

	for key, value := range categories {
		xlsx.SetCellValue("Sheet1", key, value)
		_style, err := xlsx.NewStyle(`{"fill":{"type":"pattern","color":["#EEECE1"],"pattern":1},"alignment":{"horizontal":"center","vertical":"center"},"font":{"bold":true,"family":"宋体","size":10}}`)
		if err == nil {
			xlsx.SetCellStyle("Sheet1", key, key, _style)
		}
	}

	for k, v := range colWidths {
		xlsx.SetColWidth("Sheet1", k, k, v)
	}

	for i, v := range strings.Split(fmt.Sprintf("%v", selectedItems), "|") {
		selectedItemMap[v] = i
	}
	p := map[string]struct{}{
		"unit_price": {},
	}
	v := req.(map[string]interface{})
	for index, vv := range v["list"].([]interface{}) {

		var (
			columIndex  = 'A'
			columOffset = 1
		)
		for kkk, vvv := range util.Struct2Map(vv, "json") {

			if len(selectedItemMap) > 0 {
				if i, ok := selectedItemMap[kkk]; !ok {
					continue
				} else {
					columOffset = i
				}
			}

			cell := fmt.Sprintf("%c", int(columIndex)+columOffset) + convert.ToString(index+2)

			if reflect.TypeOf(vvv).Kind() == reflect.Ptr {
				vOf := reflect.ValueOf(vvv)
				if vOf.IsNil() {
					vvv = ""
				} else {
					vvv = vOf.Elem()
				}
			}

			if kkk == "updated_at" {
				vvv = pkgTime.Format(vvv.(int64))
			}

			if kkk == "status" {
				vvv = statusMap[int(vvv.(int64))]
			}

			if _, ok := p[kkk]; ok {
				vvv = pkgUtil.Decimal(float64(vvv.(uint64))/10000.0, 5)
			}

			xlsx.SetCellValue("Sheet1", cell, vvv)
		}
		xlsx.SetRowHeight("Sheet1", index+2, 18)
	}

	xlsx.SetSheetName("Sheet1", "第一页")

	filPath, fileName := a.getExportPath(convert.ToString(time.Now().UnixMilli())+".csv", 1)
	err := xlsx.SaveAs(filPath)
	if err != nil {
		return err
	}

	req = fileName

	return req
}

func (a *BusinessTypeSrv) getExportPath(fileName string, bizTy int) (string, string) {

	var (
		bizTyMap = map[int]string{
			1: "business_type",
		}
	)

	relativePath := fmt.Sprintf("%v/export/%v", bizTyMap[bizTy], fileName)

	return serviceUtil.GetFilePath(
		fmt.Sprintf("%v/%v",
			serviceUtil.FileStorage(),
			relativePath),
	), relativePath
}
